package ControlLayer;

import java.util.ArrayList;
import java.util.Arrays;

import DBLayer.DBConnection;
import DBLayer.DBEmployee;
import DBLayer.DBGuest;
import DBLayer.DBPerson;
import DBLayer.GetMaxId;
import DBLayer.IFDBEmployee;
import DBLayer.IFDBGuest;
import DBLayer.IFDBPerson;
import ModelLayer.Agency;
import ModelLayer.DiscountGroup;
import ModelLayer.Employee;
import ModelLayer.KeyWord;
import ModelLayer.Person;
import ModelLayer.Guest;
import ModelLayer.Room;

public class PersonCtr {

	public PersonCtr() {

	}

	public Person loginGUI(String logname, char[] password)
			throws PersonException {
		IFDBPerson dbPerson = new DBPerson();
		Person person = dbPerson.loginGUI(logname, false);
		if (Arrays.equals(person.getPassword().toCharArray(), password))
			return person;
		else
			throw new PersonException("Log in name or password not found");
	}

	public int insertPerson(String fname, String lname, String address,
			String country, String phone, String email, String logId,
			String password, int authLevel, String ptype) {
		int personId = 0;
		Person person = new Person();
		person.setfName(fname);
		person.setlName(lname);
		person.setAddress(address);
		person.setPhone(phone);
		person.setCountry(country);
		person.setEmail(email);
		person.setLogId(logId);
		person.setPassword(password);
		person.setAuthLevel(authLevel);
		person.setPtype(KeyWord.valueOf(ptype));
		person.generateLogId();
		person.generatePassword();
		try {
			DBConnection.startTransaction();
			DBPerson dbPerson = new DBPerson();
			personId = dbPerson.insertPerson(person);
			DBConnection.commitTransaction();
		} catch (Exception e) {
			DBConnection.rollbackTransaction();
		}
		return personId;
	}

	public Guest getGuestPersonWithoutAssociation(int guestId)
			throws PersonException {
		Person person = new Person();
		IFDBPerson dbPerson = new DBPerson();
		person = dbPerson.getPerson(guestId, true);
		Guest guest = new Guest();
		IFDBGuest dbGuest = new DBGuest();
		guest = dbGuest.getGuest(person.getID(), false);

		if (guest == null) {
			throw new PersonException("Guest is not found");
		}

		guest.setAddress(person.getAddress());
		guest.setfName(person.getfName());
		guest.setlName(person.getlName());
		guest.setPhone(person.getPhone());
		guest.setCountry(person.getCountry());
		guest.setEmail(person.getEmail());
		guest.setPtype(person.getPtype());
		guest.setID(person.getID());
		guest.setLogId(person.getLogId());
		guest.setPassword(person.getPassword());
		guest.setAuthLevel(person.getAuthLevel());

		return guest;
	}

	public Guest getGuest(int personId) throws PersonException {
		Person person = new Person();
		IFDBPerson dbPerson = new DBPerson();
		person = dbPerson.getPerson(personId, true);
		if (person == null) {
			throw new PersonException("Person not found");
		}
		if (person.getPtype() == KeyWord.Guest) {
			Guest guest = new Guest();
			IFDBGuest dbGuest = new DBGuest();
			guest = dbGuest.getGuest(person.getID(), true);
			guest.setAddress(person.getAddress());
			guest.setfName(person.getfName());
			guest.setlName(person.getlName());
			guest.setPhone(person.getPhone());
			guest.setCountry(person.getCountry());
			guest.setEmail(person.getEmail());
			guest.setPtype(person.getPtype());
			guest.setID(person.getID());
			guest.setLogId(person.getLogId());
			guest.setPassword(person.getPassword());
			guest.setAuthLevel(person.getAuthLevel());
			return guest;

		} else {
			throw new PersonException("Guest not found");
		}
	}

	public Employee getEmployee(int personId) throws PersonException {
		Person person = new Person();
		IFDBPerson dbPerson = new DBPerson();
		person = dbPerson.getPerson(personId, true);
		if (person == null) {
			throw new PersonException("Person not found");
		}
		if (person.getPtype() == KeyWord.Employee) {
			Employee employee = new Employee();
			IFDBEmployee dbEmployee = new DBEmployee();
			employee = dbEmployee.getEmployee(person.getID(), true);
			employee.setAddress(person.getAddress());
			employee.setfName(person.getfName());
			employee.setlName(person.getlName());
			employee.setPhone(person.getPhone());
			employee.setCountry(person.getCountry());
			employee.setEmail(person.getEmail());
			employee.setPtype(person.getPtype());
			employee.setID(person.getID());
			employee.setLogId(person.getLogId());
			employee.setPassword(person.getPassword());
			employee.setAuthLevel(person.getAuthLevel());
			return employee;
		} else {
			throw new PersonException("Employee not found");
		}
	}

	public Object getPerson(int personId) throws PersonException {
		Person person = new Person();
		IFDBPerson dbPerson = new DBPerson();
		person = dbPerson.getPerson(personId, true);
		if (person == null) {
			throw new PersonException("Person not found");
		}
		if (person.getPtype() == KeyWord.Guest) {
			Guest guest = new Guest();
			IFDBGuest dbGuest = new DBGuest();
			guest = dbGuest.getGuest(person.getID(), true);
			guest.setAddress(person.getAddress());
			guest.setfName(person.getfName());
			guest.setlName(person.getlName());
			guest.setPhone(person.getPhone());
			guest.setCountry(person.getCountry());
			guest.setEmail(person.getEmail());
			guest.setPtype(person.getPtype());
			guest.setID(person.getID());
			guest.setLogId(person.getLogId());
			guest.setPassword(person.getPassword());
			guest.setAuthLevel(person.getAuthLevel());
			return guest;

		} else if (person.getPtype() == KeyWord.Employee) {
			Employee employee = new Employee();
			IFDBEmployee dbEmployee = new DBEmployee();
			employee = dbEmployee.getEmployee(person.getID(), true);
			employee.setAddress(person.getAddress());
			employee.setfName(person.getfName());
			employee.setlName(person.getlName());
			employee.setPhone(person.getPhone());
			employee.setCountry(person.getCountry());
			employee.setEmail(person.getEmail());
			employee.setPtype(person.getPtype());
			employee.setID(person.getID());
			employee.setLogId(person.getLogId());
			employee.setPassword(person.getPassword());
			employee.setAuthLevel(person.getAuthLevel());
			return employee;
		} else
			return null;

	}

	public void updatePerson(int guestId, String fname, String lname,
			String address, String country, String phone, String email,
			int authLevel) {
		Person person = new Person();
		person.setID(guestId);
		person.setfName(fname);
		person.setlName(lname);
		person.setAddress(address);
		person.setPhone(phone);
		person.setCountry(country);
		person.setEmail(email);
		person.setAuthLevel(authLevel);
		try {
			DBConnection.startTransaction();
			DBPerson dbPerson = new DBPerson();
			dbPerson.updatePerson(person);
			DBConnection.commitTransaction();
		} catch (Exception e) {
			DBConnection.rollbackTransaction();
		}
	}

	public void deletePerson(int personId) {
		try {
			DBConnection.startTransaction();
			IFDBPerson dbPerson = new DBPerson();
			dbPerson.deletePerson(personId);
			DBConnection.commitTransaction();
		} catch (Exception e) {
			DBConnection.rollbackTransaction();
		}
	}

	public int createGuest(String fname, String lname, String address,
			String country, String phone, String email, String ptype,
			String passNumber, int agencyId, int discountId) {
		Guest guest = new Guest();
		guest.generatePassword();
		int nextId = GetMaxId.getMaxId("Select max(personId) from person") + 1;
		guest.setLogId(Integer.toString(nextId));

		int guestId = insertPerson(fname, lname, address, country, phone,
				email, guest.getLogId(), guest.getPassword(), 5, ptype);
		// create guest

		guest.setID(guestId);
		guest.setPassNumber(passNumber);
		if (agencyId != 0)
			guest.setAgency(new Agency(agencyId));
		if (discountId != 0)
			guest.setDiscountGroup(new DiscountGroup(discountId));

		try {
			DBConnection.startTransaction();
			DBGuest dbGuest = new DBGuest();
			dbGuest.insertGuest(guest);
			DBConnection.commitTransaction();
		} catch (Exception e) {
			DBConnection.rollbackTransaction();
		}
		return guestId;
	}

	public void updateGuestRoom(int guestId, Room room) {
		IFDBGuest dbGuest = new DBGuest();
		dbGuest.updateGuestRoom(guestId, room);
	}

	public void updateGuest(int guestId, String fname, String lname,
			String address, String country, String phone, String email,
			int authLevel, String passNumber, int agencyId, int discountId,
			int roomId) {
		updatePerson(guestId, fname, lname, address, country, phone, email,
				authLevel);
		Guest guest = new Guest();
		guest.setID(guestId);
		guest.setPassNumber(passNumber);
		if (agencyId != 0)
			guest.setAgency(new Agency(agencyId));

		if (discountId != 0)
			guest.setDiscountGroup(new DiscountGroup(discountId));

		if (roomId != 0)
			guest.setCurrentRoom(new Room(roomId));
		try {
			DBConnection.startTransaction();
			IFDBGuest dbGuest = new DBGuest();
			dbGuest.updateGuest(guest);
			DBConnection.commitTransaction();
		} catch (Exception e) {
			DBConnection.rollbackTransaction();
		}
	}

	public void deleteGuest(int guestId) {
		try {
			DBConnection.startTransaction();
			IFDBGuest dbGuest = new DBGuest();
			dbGuest.deleteGuest(guestId);
			DBConnection.commitTransaction();
		} catch (Exception e) {
			DBConnection.rollbackTransaction();
		}
		deletePerson(guestId);
	}

	public ArrayList<Guest> getGuestForRoom(int roomId) {
		IFDBGuest dbGuest = new DBGuest();
		ArrayList<Guest> guests = new ArrayList<Guest>();
		guests = dbGuest.getGuestForRoom(roomId, false);
		for (Guest guest : guests) {
			try {
				guest = getGuestPersonWithoutAssociation(guest.getID());
			} catch (PersonException e) {

			}
			// guest.setAddress(person.getAddress());
			// guest.setfName(person.getfName());
			// guest.setlName(person.getlName());
			// guest.setPhone(person.getPhone());
			// guest.setCountry(person.getCountry());
			// guest.setEmail(person.getEmail());
			// guest.setPtype(person.getPtype());
			// guest.setID(person.getID());
			// guest.setLogId(person.getLogId());
			// guest.setPassword(person.getPassword());
			// guest.setAuthLevel(person.getAuthLevel());
		}
		return guests;
	}

	public ArrayList<Guest> getAllGuest() {
		IFDBGuest dbGuest = new DBGuest();
		ArrayList<Guest> guests = new ArrayList<Guest>();
		guests = dbGuest.getAllGuest(true);
		for (Guest guest : guests) {
			Person person;
			try {
				person = (Person) getPerson(guest.getID());
				guest.setAddress(person.getAddress());
				guest.setfName(person.getfName());
				guest.setlName(person.getlName());
				guest.setPhone(person.getPhone());
				guest.setCountry(person.getCountry());
				guest.setEmail(person.getEmail());
				guest.setPtype(person.getPtype());
				guest.setID(person.getID());
				guest.setLogId(person.getLogId());
				guest.setPassword(person.getPassword());
				guest.setAuthLevel(person.getAuthLevel());
			} catch (PersonException e) {
			}
		}
		return guests;
	}

	public int createEmployee(String fname, String lname, String address,
			String country, String phone, String email, String ptype,
			String ssn, String position) {
		Employee employee = new Employee();
		employee.generatePassword();
		int nextId = GetMaxId.getMaxId("Select max(personId) from person") + 1;

		employee.setLogId(Integer.toString(nextId));
		int authLevel = 1;
		if (KeyWord.valueOf(position) == KeyWord.Manager)
			authLevel = 2;
		else if (KeyWord.valueOf(position) == KeyWord.Receptionist)
			authLevel = 3;
		else if (KeyWord.valueOf(position) == KeyWord.Instructor)
			authLevel = 4;
		int employeeId = insertPerson(fname, lname, address, country, phone,
				email, employee.getLogId(), employee.getPassword(), authLevel,
				ptype);
		// create guest

		employee.setID(employeeId);
		employee.setSsn(ssn);
		employee.setPosition(KeyWord.valueOf(position));
		try {
			DBConnection.startTransaction();
			IFDBEmployee dbEmployee = new DBEmployee();
			dbEmployee.insertEmployee(employee);
			DBConnection.commitTransaction();
		} catch (Exception e) {
			DBConnection.rollbackTransaction();
		}
		return employeeId;
	}

	public void updateEmployee(int employeeId, String fname, String lname,
			String address, String country, String phone, String email,
			int authLevel, String ssn, String position) {
		updatePerson(employeeId, fname, lname, address, country, phone, email,
				authLevel);
		Employee employee = new Employee();
		employee.setID(employeeId);
		employee.setSsn(ssn);
		employee.setPosition(KeyWord.valueOf(position));
		try {
			DBConnection.startTransaction();
			IFDBEmployee dbEmployee = new DBEmployee();
			dbEmployee.updateEmployee(employee);
			DBConnection.commitTransaction();
		} catch (Exception e) {
			DBConnection.rollbackTransaction();
		}

	}

	public void deleteEmployee(int employeeId) {
		try {
			DBConnection.startTransaction();
			IFDBEmployee dbEmployee = new DBEmployee();
			dbEmployee.deleteEmployee(employeeId);
			DBConnection.commitTransaction();
		} catch (Exception e) {
			DBConnection.rollbackTransaction();
		}
		deletePerson(employeeId);
	}

	public ArrayList<Employee> getAllEmployee() {
		IFDBEmployee dbEmployee = new DBEmployee();
		ArrayList<Employee> employees = dbEmployee.getAllEmployee(true);
		for (Employee employee : employees) {
			Person person;
			try {
				person = (Person) getPerson(employee.getID());
				employee.setAddress(person.getAddress());
				employee.setfName(person.getfName());
				employee.setlName(person.getlName());
				employee.setPhone(person.getPhone());
				employee.setCountry(person.getCountry());
				employee.setEmail(person.getEmail());
				employee.setPtype(person.getPtype());
				employee.setID(person.getID());
				employee.setLogId(person.getLogId());
				employee.setPassword(person.getPassword());
				employee.setAuthLevel(person.getAuthLevel());
			} catch (PersonException e) {
			}

		}
		return employees;
	}

}
